package com.gcloud.mesh.dcs.service;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.mvel2.MVEL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.cms20190101.models.DescribeMetricLastResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.gcloud.mesh.asset.dao.CloudResourceDao;
import com.gcloud.mesh.asset.entity.CloudResourceEntity;
import com.gcloud.mesh.dcs.dao.AppDao;
import com.gcloud.mesh.dcs.entity.AppEntity;
import com.gcloud.mesh.dcs.enums.DeviceThresholdType;
import com.gcloud.mesh.supplier.dao.SupplierDao;
import com.gcloud.mesh.supplier.enums.SystemType;

import lombok.extern.slf4j.Slf4j;

/**
 * 阿里ecs 内存 计算
 */
@Component
@Slf4j
public class AliMemSpaceThreholdService implements IDeviceThresholdService {

   @Autowired
    private SupplierDao supplierDao;

   @Autowired
    private CloudResourceDao cloudResourceDao;

   @Autowired
    private AppDao appDao;

    @Override
    public DeviceThresholdType device() {
        return DeviceThresholdType.ALI_MEM_SPACE;
    }

    private Double getEcsMemValue(String regionId,String accessKeyId, String secret,String instanceId){

        Double val = 0.0;
        Config config = new Config()
                // 您的AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 您的AccessKey Secret
                .setAccessKeySecret(secret);
        // 访问的域名
        config.endpoint = "metrics."+regionId+".aliyuncs.com";
        try {
            com.aliyun.cms20190101.Client client =  new com.aliyun.cms20190101.Client(config);
            com.aliyun.cms20190101.models.DescribeMetricLastRequest describeMetricLastRequest = new com.aliyun.cms20190101.models.DescribeMetricLastRequest()
                    .setMetricName("memory_usedutilization")
                    .setDimensions("[{\"instanceId\": \""+instanceId+"\"}]")
                    .setNamespace("acs_ecs_dashboard");
            // 内存
            DescribeMetricLastResponseBody resp = client.describeMetricLast(describeMetricLastRequest).getBody();
            if(resp.getSuccess() && "200".equals(resp.getCode())){
                JSONArray objects = JSONArray.parseArray(resp.getDatapoints());
                if(objects.isEmpty()) return val;
                JSONObject jsonObject = objects.getJSONObject(0);
                log.debug("**********"+JSON.toJSONString(resp)+"**********");
                log.debug("**********成功查询ali-mem监控信息**********");
                return jsonObject.getBigDecimal("Average").doubleValue();
            }
        } catch (Exception _error) {
            log.error("查询ali-mem监控信息异常",_error);
        }
        return val;

    }

    @Override
    public Boolean checkScheduler(String appid, String operation, Double value) {
        // 获取ecs 服务器监控数据
        AppEntity appEntity = appDao.getById(appid);
        if(appEntity==null) return false;
        CloudResourceEntity cloudResourceEntity = cloudResourceDao.findOneByProperty("id", appEntity.getCloudResourceId());
        if(cloudResourceEntity==null) return false;
        String configValue = supplierDao.getConfigValueByDatacenterId(SystemType.ALI.getName(),cloudResourceEntity.getDatacenterId());
        if(StringUtils.isBlank(configValue)) return false;
        JSONObject configJson = JSONObject.parseObject(configValue);
        String regionId = configJson.getString("regionId");
        String accessKeyId = configJson.getString("accessKeyId");
        String secret = configJson.getString("accessSecret");
        String instanceId = appid;
        Double memVal = getEcsMemValue(regionId,accessKeyId, secret,instanceId);
        String evalExpression = String.format("memVal %s reqVal",operation);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("memVal",memVal);
        paramMap.put("reqVal",value);
        Boolean aBoolean = MVEL.evalToBoolean(evalExpression, paramMap);
        log.info("监控项[ALI_MEM_UTIL] id:{}, memVal:{},reqVal:{},evalExpression:{},result:{}", appid, memVal,value,evalExpression,aBoolean);
        return aBoolean;
    }
}
